package org.aplikator.client.local.widgets;

import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.ButtonGroup;
import com.github.gwtbootstrap.client.ui.Nav;
import com.github.gwtbootstrap.client.ui.Navbar;
import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.cellview.client.HasKeyboardPagingPolicy;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import org.aplikator.client.local.Aplikator;
import org.aplikator.client.local.command.MainPanelTitleCallback;
import org.aplikator.client.local.panels.FluidNavbar;
import org.aplikator.client.shared.data.*;
import org.aplikator.client.shared.descriptor.PropertyDTO;
import org.aplikator.client.shared.descriptor.RecordsPageDTO;
import org.aplikator.client.shared.descriptor.ViewDTO;
import org.aplikator.client.shared.rpc.ParameterWrapperGetPage;
import org.jboss.errai.common.client.api.RemoteCallback;
import java.util.List;

public class TableListerWidget extends Composite implements TableInterface {

    public interface TableListerWidgetResources extends CellList.Resources {
        public static final TableListerWidgetResources INSTANCE = GWT.create(TableListerWidgetResources.class);

        @Source("TableListerWidget.css")
        public TableWidgetCss css();

        @Source("TableListerCellList.css")
        CellList.Style cellListStyle();
    }

    public interface TableWidgetCss extends CssResource {
        public String tableBody();

        public String tableColumn();

        public String tableHeader();

        public String tableHeaderCell();

        public String tableOddRow();

        public String tableEvenRow();

        public String tableSelectedRow();

        public String tableHoveredRow();

        public String tableNavigationPanel();

        public String toolbarButton();

        public String listPanel();

        public String formPanel();
    }

    static {
        TableListerWidgetResources.INSTANCE.css().ensureInjected();
        TableListerWidgetResources.INSTANCE.cellListStyle().ensureInjected();
    }

    private static class RecordCell extends AbstractCell<Record> {
        @Override
        public void render(Context ctx, Record value, SafeHtmlBuilder sb) {
            if (value != null) {
                sb.appendHtmlConstant(value.getPreview());
            }
        }
    }

    private final SplitLayoutPanel dataPanel;

    final SimplePanel navigationHolder = new SimplePanel();

    private final Navbar navigationPanel;
    private final InlineHTML statusLabel;
    private final Label searchID;
    private final Button buttonFirstPage;
    private final Button buttonPrevPage;
    private final Button buttonNextPage;
    private final Button buttonLastPage;
    private final TextBox searchField;
    private final Button buttonSearch;
    private Button buttonCreate;
    private Button buttonOpen;
    private Button buttonDelete;
    private final Button buttonCopy;
    private final Button buttonReload;
    private final Button buttonClose;
    private final Button buttonSave;

    private final CellList<Record> cellList;
    private final SingleSelectionModel<Record> selectionModel;
    private final ListPanel pagerPanel;

    private FormWidget form;
    private DeckPanel formHolder;
    private Label noForm;

    private MainPanelTitleCallback titleCallback;
    private ViewDTO view;
    private List<Record> pageData;
    private int pageOffset = 0;
    private int pageSize = 0;
    private String searchArgument;
    private int recordCount = 0;

    private PrimaryKey ownerPrimaryKey;
    private PropertyDTO ownerProperty;
    private HasFields ownerForm;

    RecordContainer recordContainer;

    public TableListerWidget(ViewDTO view, PropertyDTO ownerProperty, HasFields ownerForm) {
        super();
        this.view = view;
        this.pageSize = view.getPageSize();
        this.ownerProperty = ownerProperty;
        this.ownerForm = ownerForm;
        final DockLayoutPanel basePanel = new DockLayoutPanel(Unit.PX);
        initWidget(basePanel);
        // Top navigation panel
        navigationPanel = new FluidNavbar();
        navigationHolder.add(navigationPanel);
        basePanel.addNorth(navigationHolder, 44);
        Nav nav = new Nav();
        navigationPanel.add(nav);
        // paging buttons
        ButtonGroup pagingButtons = new ButtonGroup();
        buttonFirstPage = new Button("", IconType.STEP_BACKWARD);//new Image(TableWidgetResources.INSTANCE.first());
        pagingButtons.add(buttonFirstPage);
        buttonFirstPage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonFirstPageClicked();
            }
        });

        buttonPrevPage = new Button("", IconType.CHEVRON_LEFT);//new Image(TableWidgetResources.INSTANCE.prev());
        pagingButtons.add(buttonPrevPage);
        buttonPrevPage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonPrevPageClicked();
            }
        });

        buttonNextPage = new Button("", IconType.CHEVRON_RIGHT);//new Image(TableWidgetResources.INSTANCE.next());
        pagingButtons.add(buttonNextPage);
        buttonNextPage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonNextPageClicked();
            }
        });

        buttonLastPage = new Button("", IconType.STEP_FORWARD);//new Image(TableWidgetResources.INSTANCE.last());
        pagingButtons.add(buttonLastPage);
        buttonLastPage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonLastPageClicked();
            }
        });

        nav.add(pagingButtons);

        // create, open, delete and copy buttons
        statusLabel = new InlineHTML();
        statusLabel.setStyleName(TableListerWidgetResources.INSTANCE.css().toolbarButton());
        nav.add(statusLabel);
        statusLabel.setWordWrap(false);

        ButtonGroup recordButtons = new ButtonGroup();
        nav.add(recordButtons);
        buttonCreate = new Button("Create", IconType.FILE);//new Image(TableWidgetResources.INSTANCE.create());
        recordButtons.add(buttonCreate);
        buttonCreate.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonCreateClicked();
            }
        });

        /*buttonOpen = new Button("Open");//new Image(TableWidgetResources.INSTANCE.open());
        navigationPanel.add(buttonOpen);
        buttonOpen.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonOpenClicked();
            }
        }); */

        buttonDelete = new Button("Delete", IconType.TRASH);//new Image(TableWidgetResources.INSTANCE.delete());
        recordButtons.add(buttonDelete);
        buttonDelete.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonDeleteClicked();
            }
        });

        buttonCopy = new Button("Copy", IconType.COPY);//new Image(TableWidgetResources.INSTANCE.copy());
        recordButtons.add(buttonCopy);
        buttonCopy.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonCopyClicked();
            }
        });

        buttonReload = new Button("", IconType.REFRESH);//new Image(TableWidgetResources.INSTANCE.reload());
        nav.add(buttonReload);
        buttonReload.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonReloadClicked();
            }
        });

        // search field and button
        InlineHTML strutS = new InlineHTML("&nbsp;");
        strutS.getElement().getStyle().setProperty("marginLeft", "20px");
        nav.add(strutS);

        searchID = new InlineHTML();
        searchID.setStyleName(TableListerWidgetResources.INSTANCE.css().toolbarButton());
        searchID.setWordWrap(false);
        searchField = new TextBox();
        searchField.setWidth("200px");
        searchField.setStyleName(TableListerWidgetResources.INSTANCE.css().toolbarButton());
        buttonSearch = new Button("", IconType.SEARCH);//new Image(TableWidgetResources.INSTANCE.find());
        buttonSearch.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonSearchClicked();
            }
        });
        adjustSearchLabel();
        nav.add(searchID);
        nav.add(searchField);
        nav.add(buttonSearch);

        InlineHTML strut2 = new InlineHTML("&nbsp;");
        strut2.getElement().getStyle().setProperty("marginLeft", "20px");
        nav.add(strut2);

        buttonClose = new Button("Cancel", IconType.BAN_CIRCLE);//new Image(TableWidgetResources.INSTANCE.cancel());
        buttonClose.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonCloseClicked();
            }
        });
        nav.add(buttonClose);

        buttonSave = new Button("Save", IconType.SAVE);//new Image(TableWidgetResources.INSTANCE.save());
        buttonSave.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                TableListerWidget.this.buttonSaveClicked();
            }
        });
        nav.add(buttonSave);

        // status text
        showStatus();

        // scrollable cellList
        dataPanel = new SplitLayoutPanel();
        dataPanel.addStyleName("tabledatapanel");
        basePanel.add(dataPanel);
        basePanel.addStyleName("tablebasepanel");
        cellList = new CellList<Record>(new RecordCell(), TableListerWidgetResources.INSTANCE, Record.KEY_PROVIDER);
        selectionModel = new SingleSelectionModel<Record>( Record.KEY_PROVIDER);
        cellList.setSelectionModel(selectionModel);
        cellList.setKeyboardPagingPolicy(HasKeyboardPagingPolicy.KeyboardPagingPolicy.INCREASE_RANGE);
        cellList.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.BOUND_TO_SELECTION);
        cellList.setLoadingIndicator(new LoadingLabel());

        selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
            public void onSelectionChange(SelectionChangeEvent event) {
                buttonOpenClicked();
            }
        });

        pagerPanel = new ListPanel(cellList);

        form = new FormWidget(this.view, this, this.ownerForm);
        noForm = new com.github.gwtbootstrap.client.ui.Label("No record selected");
        formHolder = new DeckPanel();
        formHolder.add(noForm);
        formHolder.add(form);
        formHolder.showWidget(0);

        pagerPanel.addStyleName(TableListerWidgetResources.INSTANCE.css().listPanel());

        ScrollPanel formScroller = new ScrollPanel(formHolder);
        formScroller.addStyleName("formscroller");
        formScroller.addStyleName(TableListerWidgetResources.INSTANCE.css().formPanel());

        dataPanel.addWest(pagerPanel, 250);
        dataPanel.add(formScroller);

    }




    public void reload(String searchArgument) {
    	this.searchArgument = searchArgument;
        loadDataSearch();        
    }


    public void reload() {
    	this.searchArgument=null;
        if (view.getActiveQueryParameters() != null && view.getActiveQueryParameters().size() > 0) {
            final DialogBox dialogBox = createParamDialogBox();
            dialogBox.setAnimationEnabled(true);
            dialogBox.center();
            // dialogBox.show();
        } else {
            loadData();
        }
    }

    private void adjustSearchLabel() {

        if (this.view.getActivePrimarySortProperty() != null && !this.view.getActivePrimarySortProperty().equals(this.view.getEntity().getPrimaryKey())) {
            searchID.setText("Search in " + this.view.getActivePrimarySortProperty().getLocalizedName() + ": ");
            searchID.setVisible(true);
            searchField.setVisible(true);
            buttonSearch.setVisible(true);
        } else {
            searchID.setText("Not sorted");
            searchID.setVisible(false);
            searchField.setVisible(false);
            buttonSearch.setVisible(false);
        }

    }





    private void loadData() {
    	if (searchArgument!=null) {
    		loadDataSearch();
    	} else {
    		resetGrid();
    		Aplikator.aplikatorService.call( new RemoteCallback<Integer>() {
            @Override
            public void callback(Integer resp) {
                recordCount = resp;
                showStatus();
                //cellList.setPageSize(Math.min(recordCount, pageSize));
                Aplikator.aplikatorService.call( new RemoteCallback<RecordsPageDTO>() {
                    @Override
                    public void callback(RecordsPageDTO resp) {
                    	TableListerWidget.this.pageData = resp.getRecords();
                        redrawPage();
                        //redrawSelectedRow();
                        showStatus();
                    }
                }).getPage(new ParameterWrapperGetPage(view.getId(), ownerProperty), (ownerPrimaryKey==null)?null:ownerPrimaryKey.getSerializationString(), pageOffset, pageSize);

            }
        }).getRecordCount(new ParameterWrapperGetPage(view.getId(), ownerProperty), (ownerPrimaryKey==null)?null:ownerPrimaryKey.getSerializationString(), false);

    	}
    }

    private void loadDataSearch() {
        resetGrid();
        Aplikator.aplikatorService.call( new RemoteCallback<SearchResult>() {
            @Override
            public void callback(SearchResult resp) {
                TableListerWidget.this.pageData = resp.getRecords();
                recordCount = resp.getCount().intValue();
                redrawPage();
                //redrawSelectedRow();
                showStatus();
            }
        }).getPageSearch(view.getId(),searchArgument, pageOffset, pageSize);
    }


    private void resetGrid(){
        pageData = null;
        cellList.setRowCount(1);
        cellList.setPageSize(1);
        cellList.setVisibleRangeAndClearData(cellList.getVisibleRange(), true);

        //cellList.setPageSize(0);

    }

    private void redrawPage() {
        //resetGrid();
        cellList.setRowCount(pageData.size(), true);
        cellList.setPageSize(pageData.size());
        cellList.setRowData(0, pageData);
        if (pageData.isEmpty()){
            selectionModel.clear();
        }else{
            selectionModel.setSelected(pageData.get(0),true);
        }
    }


    private DialogBox createParamDialogBox() {
        // Create a dialog box and set the caption text

        // Create a table to layout the content
        VerticalPanel dialogContents = new VerticalPanel();
        final DialogBox dialogBox = new DialogBox();
        dialogBox.setText("Input query parameters");
        dialogBox.setWidget(dialogContents);
        dialogContents.setSpacing(4);
        dialogBox.setWidget(dialogContents);
        final int paramCount = view.getActiveQueryParameters().size();
        final TextBox[] paramValues = new TextBox[paramCount];
        for (int i = 0; i < paramCount; i++) {
            HorizontalPanel paramPane = new HorizontalPanel();
            paramPane.add(new Label(view.getActiveQueryParameters().get(i).getName()));
            paramValues[i] = new TextBox();

            paramPane.add(paramValues[i]);
            dialogContents.add(paramPane);
        }

        // Add a close button at the bottom of the dialog
        Button closeButton = new Button("OK", new ClickHandler() {
            @SuppressWarnings("unchecked")
            public void onClick(ClickEvent event) {
                dialogBox.hide();
                StringBuilder title = new StringBuilder();
                for (int i = 0; i < paramCount; i++) {
                    view.getActiveQueryParameters().get(i).setValue(paramValues[i].getText());
                    title.append(view.getActiveQueryParameters().get(i).getName());
                    title.append(": ");
                    title.append(view.getActiveQueryParameters().get(i).getValue());
                    if (i < paramCount - 1) {
                        title.append(", ");
                    }
                }
                if (titleCallback != null) {
                    titleCallback.setTitle(title.toString());
                }
                loadData();
            }
        });
        dialogContents.add(closeButton);
        if (LocaleInfo.getCurrentLocale().isRTL()) {
            dialogContents.setCellHorizontalAlignment(closeButton, HasHorizontalAlignment.ALIGN_LEFT);

        } else {
            dialogContents.setCellHorizontalAlignment(closeButton, HasHorizontalAlignment.ALIGN_RIGHT);
        }

        // Return the dialog box
        return dialogBox;
    }





    public void applySorting(PropertyDTO sortProperty, boolean ascending) {
        //this.view.setSortProperty(sortProperty);
        //this.view.setSortAscending(ascending);
        adjustSearchLabel();
        loadData();
    }

    public PrimaryKey getSelectedPrimaryKey() {
        Record rec = getSelectedRecord();
        return rec==null?null:rec.getPrimaryKey();
    }

    public Record getSelectedRecord() {
        return this.selectionModel.getSelectedObject();
    }

    private void buttonLastPageClicked() {
            if (pageSize > 0) {
                pageOffset = recordCount - pageSize;
                loadData();
            }
    }

    private void buttonNextPageClicked() {
            if (pageSize > 0) {
                pageOffset = Math.min(recordCount - 1, pageOffset + pageSize);
                loadData();
            }
    }

    private void buttonPrevPageClicked() {
            if (pageSize > 0) {
                pageOffset = Math.max(0, pageOffset - pageSize);
                loadData();
            }
    }

    private void buttonFirstPageClicked() {
            if (pageSize > 0) {
                pageOffset = 0;
                loadData();
            }
    }

    private void buttonSearchClicked() {// TODO add support for pageSize <-1

        view.setSearchString(searchField.getText());
        search();

    }

    public void search() {
        if (view.getSearchString() != null && !"".equals(view.getSearchString())) {
            Aplikator.aplikatorService.call( new RemoteCallback<Integer>() {
                @Override
                public void callback(Integer resp) {
                    pageOffset = resp;
                    loadData();
                }
            }).getRecordCount(new ParameterWrapperGetPage(view.getId(), ownerProperty), (ownerPrimaryKey==null)?null:ownerPrimaryKey.getSerializationString(), true);
        } else {
            loadData();
        }
    }

    private void showStatus() {
        String text = "";
        if (pageSize > 0) {
            text = "   Records: " + (pageOffset + 1) + " - " + (Math.min(recordCount, pageOffset + pageSize)) + " of " + recordCount + "   ";
        } else {
            text = "   Records: " + recordCount + "   ";
        }
        statusLabel.setText(text);
    }

    private void buttonCreateClicked() {
        if (ownerProperty != null) {
            form.addRecord(recordContainer, ownerProperty, ownerPrimaryKey, null);
        } else {
            form.addRecord(new RecordContainer(), null, null, null);
        }
    }

    private void buttonOpenClicked() {
        openForm();
    }

    private void buttonCloseClicked() {
        closeForm(new Command() {
            public void execute() {

            }
        });

    }

    private void closeForm(Command afterConfirmation) {
        form.onClose(afterConfirmation);
    }

    private void openForm() {
        formHolder.showWidget(1);
        if (ownerProperty != null) {
            form.displayRecord(getSelectedPrimaryKey(), recordContainer);
        } else {
            form.displayRecord(getSelectedPrimaryKey(), new RecordContainer());
        }
    }

    private void buttonSaveClicked() {
        form.save();
    }

    public void save() {
        if (form != null) {
            form.save();
        }
    }

    private void buttonDeleteClicked() {
        if (ownerProperty != null) {
            recordContainer.addRecord(view, getSelectedRecord(), null, Operation.DELETE);
            pageData.remove(getSelectedRecord());
            redrawPage();
        } else {
            RecordContainer newContainer = new RecordContainer();
            newContainer.addRecord(view, getSelectedRecord(), null, Operation.DELETE);
            Aplikator.aplikatorService.call( new RemoteCallback<RecordContainer>() {
                @Override
                public void callback(RecordContainer records) {
                    pageData.remove(getSelectedRecord());
                    redrawPage();
                }
            }).processRecords(newContainer);
        }
    }

    private void buttonCopyClicked() {
        if (ownerProperty != null) {
            form.addRecord(recordContainer, ownerProperty, ownerPrimaryKey, getSelectedRecord());
        } else {
            form.addRecord(new RecordContainer(), null, null, getSelectedRecord());
        }
    }

    private void buttonReloadClicked() {
        reload();
    }

    public void addRecord(Record record) {
        pageData.add(record);
        redrawPage();
    }

    public void updateRecord(Record record) {
        for (int i = 0; i < pageData.size(); i++) {
            Record rec = pageData.get(i);
            if (rec.getPrimaryKey().equals(record.getPrimaryKey())) {
                pageData.set(i, record);
                break;
            }
        }
        redrawPage();
    }

    public PrimaryKey getOwnerPrimaryKey() {
        return ownerPrimaryKey;
    }

    public void setOwnerPrimaryKey(PrimaryKey value) {
        ownerPrimaryKey = value;
        reload();
    }

    public void setRecordContainer(RecordContainer recordContainer) {
        this.recordContainer = recordContainer;
    }

    private void adjustNavigationPanel() {
       // buttonOpen.setVisible(gridMode);
       // buttonReload.setVisible(gridMode);
       // buttonClose.setVisible(!gridMode);
       // buttonSave.setVisible(!gridMode && (ownerForm == null));
       // statusLabel.setVisible(gridMode);

    }

    public void setTitleCallback(MainPanelTitleCallback titleCallback) {
        this.titleCallback = titleCallback;
    }

    public void setDirty(boolean dirty) {
        // for (Form nestedForm:nestedForms){
        // nestedForm.setDirty(dirty);
        // }
    }

    private boolean enabled = true;
    @Override
    public void setEnabled(boolean enabled){
         //TODO implement table controls disabling
    }


    /**
     * A scrolling pager that automatically increases the range every time the
     * scroll bar reaches the bottom.
     */
    private static class ListPanel extends Composite {

        private final ScrollPanel scrollable = new ScrollPanel();

        public ListPanel(CellList list) {
            initWidget(scrollable);

            // Do not let the scrollable take tab focus.
            scrollable.getElement().setTabIndex(-1);
            scrollable.setWidget(list);

        }

     }



//    /**
//     * A scrolling pager that automatically increases the range every time the
//     * scroll bar reaches the bottom.
//     */
//    private static class ShowMorePagerPanel extends AbstractPager {
//
//        /**
//         * The default increment size.
//         */
//        private static final int DEFAULT_INCREMENT = 20;
//
//        /**
//         * The increment size.
//         */
//        private int incrementSize = DEFAULT_INCREMENT;
//
//        /**
//         * The last scroll position.
//         */
//        private int lastScrollPos = 0;
//
//        /**
//         * The scrollable panel.
//         */
//        private final ScrollPanel scrollable = new ScrollPanel();
//
//        /**
//         * Construct a new {@link ShowMorePagerPanel}.
//         */
//        public ShowMorePagerPanel() {
//            initWidget(scrollable);
//
//            // Do not let the scrollable take tab focus.
//            scrollable.getElement().setTabIndex(-1);
//
//            // Handle scroll events.
//            scrollable.addScrollHandler(new ScrollHandler() {
//                public void onScroll(ScrollEvent event) {
//                    // If scrolling up, ignore the event.
//                    int oldScrollPos = lastScrollPos;
//                    lastScrollPos = scrollable.getVerticalScrollPosition();
//                    if (oldScrollPos >= lastScrollPos) {
//                        return;
//                    }
//
//                    HasRows display = getDisplay();
//                    if (display == null) {
//                        return;
//                    }
//                    int maxScrollTop = scrollable.getWidget().getOffsetHeight()
//                            - scrollable.getOffsetHeight();
//                    if (lastScrollPos >= maxScrollTop) {
//                        // We are near the end, so increase the page size.
//                        int newPageSize = Math.min(
//                                display.getVisibleRange().getLength() + incrementSize,
//                                display.getRowCount());
//                        display.setVisibleRange(0, newPageSize);
//                    }
//                }
//            });
//        }
//
//        /**
//         * Get the number of rows by which the range is increased when the scrollbar
//         * reaches the bottom.
//         *
//         * @return the increment size
//         */
//        public int getIncrementSize() {
//            return incrementSize;
//        }
//
//        @Override
//        public void setDisplay(HasRows display) {
//            assert display instanceof Widget : "display must extend Widget";
//            scrollable.setWidget((Widget) display);
//            super.setDisplay(display);
//        }
//
//        /**
//         * Set the number of rows by which the range is increased when the scrollbar
//         * reaches the bottom.
//         *
//         * @param incrementSize the incremental number of rows
//         */
//        public void setIncrementSize(int incrementSize) {
//            this.incrementSize = incrementSize;
//        }
//
//        @Override
//        protected void onRangeOrRowCountChanged() {
//        }
//    }
//
//    private static class RangeLabelPager extends AbstractPager {
//
//        /**
//         * The label that shows the current range.
//         */
//        private final InlineHTML label = new InlineHTML();
//
//        /**
//         * Construct a new {@link RangeLabelPager}.
//         */
//        public RangeLabelPager() {
//            initWidget(label);
//        }
//
//        @Override
//        protected void onRangeOrRowCountChanged() {
//            HasRows display = getDisplay();
//            Range range = display.getVisibleRange();
//            int start = range.getStart();
//            int end = start + range.getLength();
//            label.setText(start + " - " + end + " : " + display.getRowCount(),
//                    HasDirection.Direction.LTR);
//        }
//    }
//
//    private class AplikatorDataProvider extends AsyncDataProvider<Record> {
//        /**
//         * {@link #onRangeChanged(HasData)} is called when the table requests a new
//         * range of data. You can push data back to the displays using
//         * {@link #updateRowData(int, List)}.
//         */
//        @Override
//        protected void onRangeChanged(HasData<Record> display) {
//            // Get the new range.
//            final Range range = display.getVisibleRange();
//            final int start = range.getStart();
//            final int length = range.getLength();
//
//            Aplikator.aplikatorService.call( new RemoteCallback<List<Record>>() {
//                @Override
//                public void callback(List<Record> resp) {
//                    updateRowData(start, resp);
//                    //TableListerWidget.this.pageData = resp;
//                    //redrawPage();
//                    //redrawSelectedRow();
//                    //showStatus();
//                }
//            }).getPage(new AplikatorService.ParameterWrapperGetPage(view, ownerProperty, ownerPrimaryKey), start, length);
//
//        }
//    }

}
